<template>
  <table class="table month-table">
    <!--月份-->
    <caption :data-attr="firstDay">{{month | switchCNcaption}}</caption>
    <thead>
      <tr>
        <!--星期-->
        <th v-for="i in 7" :key="i">{{i-1 | switchCNWeek}}</th>
      </tr>
    </thead>
    <tbody>
      <!--日-->
      <tr v-for="i in daysArr.length + 1" :key="i">
        <td v-for="(item, index) in daysArr[i-1]" :key="index" :class="{disabled: isLimited && judgeIsDisabeld(item)}"><span class="cell" :data-date="item > 0 ? (year+'/'+(month+1)+'/'+item) : ''" :class="{hide: item <= 0, today: judgeIsToday(item), active: judgeIsSelected(item)}" :attr="item" @click.stop="clickOneDay(item, index)">{{item}}</span></td>
      </tr>
    </tbody>
  </table>
</template>

<script>
// import {mapGetters} from 'vuex'
import {count, deepCopyObj} from '../../assets/js/help.js'
const _langObj = JSON.parse(localStorage.getItem('langObj')) || {};
export default {
  props: {
    year: {
      type: [String, Number],
      required: true
    },
    month: {
      type: [String, Number],
      required: true
    },
    settingMode: {
      type: String,
      required: true
    },
    isLimited: Boolean,
    limitInfo: {
      type: Object
    }
  },
  data () {
    let _f = this.setFirstCalendar(this.year)
    return {
      calendar: _f
    }
  },
  watch: {
    'year': function(val) {
      let _f = this.setFirstCalendar(val);
      this.calendar = deepCopyObj(_f);
    },
  },
  computed: {
    //计算该月的天数
    days: function() {
      let _month = Number(this.month) + 1;
      let date = new Date(this.year, _month, 0);
      return date.getDate();
    },
    //计算该月的第一天是星期几--（便于控制第一行需要空几格）
    firstDay: function() {
      let date = new Date(this.year, this.month, 1);
      return date.getDay();
    },
    //把一个的月按照星期的规则切成长度为6的数组(为了保证样式一致，每个月最多可以有六行),不是该月的格子先用0代替，切成数组的原因是渲染的时候用for循环
    daysArr: function() {
      let days = this.days,
          firstDay = this.firstDay,
          _days = days,
          j = 0,
          n = 1,
          line = [],
          result = [];
      //把该月第一条前面的格子用0代替
      for(let i = 0; i < firstDay; i++) {
        line.push(0);
      }
      //将该月的第一天到最后一天每七天分隔添加入数组
      while(n <= days) {
        if(line.length < 7) {
          line.push(n);
        }
        if(line.length == 7) {
          result.push(line);
          j ++;
          line = [];
        }
        n++;
      }
      //如果最后一个数组不满七天，也用0代替
      let _l = line.length;
      if(_l < 7) {
        for(let i = _l; i < 7; i++) {
          line.push(0);
        }
        result.push(line);
        j++;
        line = [];
      }
      //如果数组的长度不够6，则最后添加全为0的数组
      let _voidNum = 6 - j;
      for(let k = 0; k < _voidNum; k++) {
        result.push([0,0,0,0,0,0,0])
      }
      return result;
    }
  },
  created () {
    for(let i = 0; i < 12; i ++) {
      let obj = this.filterDays();
      this.saveThisCalendar(obj);
    }
  },
  methods: {
    //点击某一天
    clickOneDay (d, index) {
      let m_obj = this.filterDays(),
          _idx = m_obj ? m_obj.indexOf(d) : -1;

      switch(this.settingMode) {
        case 'fullMonthly': // 整月设置
          m_obj = [];
          if(_idx < 0){
            m_obj = [];
            for(let i = 1; i <= this.days; i++) {
              m_obj.push(i);
            }
          }
          this.saveThisCalendar(m_obj);
          break;
        case 'freely': // 自由设置
          if(m_obj && _idx > -1) {
            m_obj.splice(_idx, 1);
          } else {
            m_obj.push(d);
          }
          this.saveThisCalendar(m_obj);
          break;
        //按周设置和按月设置时，因为需要跨月设置，所以将参数传给其父组件
        case 'weekly': // 按周设置
          this.$emit('dispatchAllMonth', _idx, index);
          break;
        case 'monthly': // 按月设置
          this.$emit('dispatchAllMonth', _idx, d);
          break;
        default: break;
      }
    },
    //保存 当月的 节假日设置，并将其保存到localStorage
    saveThisCalendar (m_obj) {
      let self = this,
          _calendar = this.calendar,
          fes = JSON.parse(localStorage.getItem('calendar')) || {},
          y = this.year,
          m = this.month + 1;

      m_obj = m_obj.slice(0).filter(function(x) {
        return !self.judgeIsDisabeld(x);
      })
      
      _calendar[y] = _calendar[y] ? _calendar[y] : {};
      fes[y] = fes[y] ? fes[y] : {};
      
      _calendar[y][m] = m_obj;
      
      if(m_obj.length > 0) {
        fes[y][m] = m_obj;
      } else {
        delete fes[y][m];
      }

      if(count(fes[y]) == 0) {
        delete fes[y];
      }
      
      localStorage.setItem('calendar', JSON.stringify(fes));
    },
    //当选择按月设置 来设置
    pickEachByMonthly () {
      let m_idx = arguments[0],
          m_day = arguments[1],
          m_m_obj = this.filterDays(),
          m_index = m_m_obj ? m_m_obj.indexOf(m_day) : -1;//该月是否有当前选择的日期
      
      if(m_m_obj && m_idx > -1) {
        if(m_index > -1) {
          m_m_obj.splice(m_index, 1);
        }
      } else {
        if(m_index < 0) {
          m_m_obj.push(m_day);
        }
      }
      this.saveThisCalendar(m_m_obj);
    },
    //当选择按周设置 来设置
    pickEachByWeekly () {
      let w_idx = arguments[0],
          index = arguments[1],
          w_m_obj = this.filterDays(),
          daysArr = this.daysArr,
          w_index = -1;
      for(let i = 0, len = daysArr.length; i < len; i ++) {
        let _day = daysArr[i][index];
        if(Number(_day) == 0) {continue;}
        w_index = w_m_obj ? w_m_obj.indexOf(_day) : -1;
        if(w_m_obj && w_idx > -1) {
          if(w_index > -1) {
            w_m_obj.splice(w_index, 1);
          }
        } else {
          if(w_index < 0) {
            w_m_obj.push(_day);
          }
        }
      }
      this.saveThisCalendar(w_m_obj);
    },
    //设置某一年初始的时候的选中状态
    setFirstCalendar (y) {
      let m = this.month + 1,
          _storage = JSON.parse(localStorage.getItem('calendar')),
          _f = {},
          _m = [];
      if(_storage && _storage[y] && _storage[y][m]) {
        _m = _storage[y][m];
      }
      _f[y] = {};
      _f[y][m] = _m;
      return _f;
    },
    //过滤该年该月的选中情况
    filterDays () {
      let self = this,
          calendar = this.calendar,
          y = this.year,
          m = this.month + 1,
          y_obj = calendar ? calendar[y] || {} : {},
          m_obj = y_obj ? y_obj[m] || [] : [];
      // 把该月选中的日期进行过滤，把不在范围内的日期过滤出去
      
      m_obj = m_obj.slice(0).filter(function(x) {
        return !self.judgeIsDisabeld(x);
      })

      return m_obj;
    },
    //判断是否选中
    judgeIsSelected (d) {
      let m_obj = this.filterDays();
      if(m_obj && m_obj.indexOf(d) > -1) {
        return true;
      }
      return false;
    }, 
    //判断当前日期是不是今天
    judgeIsToday (day) {
      var _today = new Date(),
          _year = _today.getFullYear(),
          _month = _today.getMonth(),
          _day = _today.getDate();
      if(_year !== Number(this.year)) {
        return false;
      }
      if(_month !== Number(this.month)) {
        return false;
      }
      if(_day !== day) {
        return false;
      }
      return true;
    },
    // 判断当前日期是否可选
    // disabeld = true 当月整月禁用
    // disabeld = false 当月整月可用
    // disabeld = 'half' 当月有一部分是可以选的，需要根据最大max、最小值min来判断，如果min或max为0，则说明该月无最小或最大的限制
    judgeIsDisabeld (day) {
      if(this.isLimited && day > 0) {
        if(this.limitInfo.disabled == 'half') {
          let _min = this.limitInfo.min,
              _max = this.limitInfo.max;
          if(_min > 0 && day < _min) {
            return true;
          }
          if(_max > 0 && day > _max) {
            return true;
          }
          return false;
        } else if(!this.limitInfo.disabled) {
          return false;
        }
        return true;
      } 
      return false;    
    }
  },
  filters: {
    //数字月份转换成中文月份
    switchCNcaption: function(month) {
      let  monthCN = '';
      switch (Number(month)) {
          case 0: monthCN = _langObj.normal_label_january; break;
          case 1: monthCN = _langObj.normal_label_february; break;
          case 2: monthCN = _langObj.normal_label_march; break;
          case 3: monthCN = _langObj.normal_label_april; break;
          case 4: monthCN = _langObj.normal_label_may; break;
          case 5: monthCN = _langObj.normal_label_june; break;
          case 6: monthCN = _langObj.normal_label_july; break;
          case 7: monthCN = _langObj.normal_label_august; break;
          case 8: monthCN = _langObj.normal_label_september; break;
          case 9: monthCN = _langObj.normal_label_october; break;
          case 10: monthCN = _langObj.normal_label_november; break;
          case 11: monthCN = _langObj.normal_label_december; break;
          default: break;
      }
      return monthCN;
    },
    //将星期的数字转成现实的值
    switchCNWeek: function(week) {
      let result = '';
      switch(Number(week)) {
        case 0: result = _langObj.normal_label_sunday; break;
        case 1: result = _langObj.normal_label_monday; break;
        case 2: result = _langObj.normal_label_tuesday; break;
        case 3: result = _langObj.normal_label_wednesday; break;
        case 4: result = _langObj.normal_label_thursday; break;
        case 5: result = _langObj.normal_label_friday; break;
        case 6: result = _langObj.normal_label_saturday; break;
        default: break;
      }
      return result;
    }
  }
}
</script>

<style lang="less" scoped>
@import '../../assets/less/base/variables.less';
.month-table {
  width: 100%;
  max-width: 100%;
  border: 1px solid @greydd;
  border-spacing: 0;
  border-collapse: collapse;
  text-align: center;
  padding-bottom: 133%;
  position: relative;
  &.disabled-month {
    tbody tr td{
      background-color: @whiteGrey;
      .cell {
        color: @grey99;
        pointer-events: none;
      }
    } 
  }
  caption {
    height: 36px;
    line-height: 36px;
    color: #FFF;
    font-size: 15px;
    font-weight: 600;
    letter-spacing: 2px;
    background-color: lighten(@blue, 3%);
  }
  thead tr{
    height: 30px;
    line-height: 30px;
    color: @greycc;
  }
  tbody tr {
    td {
      padding: 6px 4px;
      &.disabled {
        background-color: @whiteGrey;
        .cell {
          color: @grey99;
          pointer-events: none;
        }
      }
    } 
    .cell {
      display: block;
      width: 100%;
      height: 100%;
      font-size: 15px;
      // padding: 5px;
      cursor: pointer;
      position: relative;
      z-index: 2;
      -webkit-user-select: none;
      user-select: none;
      &::after {
        content: attr(attr);
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        border-radius: 46%;
        color: #FFF;
        background-color: rgba(85, 136, 221, 1);
        -webkit-backface-visibility: hidden;
        -moz-backface-visibility: hidden;
        -ms-backface-visibility: hidden;
        backface-visibility: hidden;
        transform: scale3d(0, 0, 0);
        transition: all .45s cubic-bezier(.23,1,.32,1);
        z-index: 1;
      }
      &.today {
        border-radius: 50%;
        box-shadow: inset 1px 1px 0px lighten(@red, 5%),
                    inset -1px 1px 0px lighten(@red, 5%),
                    inset 1px -1px 0px lighten(@red, 5%),
                    inset -1px -1px 0px lighten(@red, 5%);
      }
      &:hover {
        // color: #FFF;
        &::after {
          background-color: rgba(85, 136, 221, .6);
          transform: scale3d(1, 1, 1);
        }
      }
      &.active {
        &::after {
          background-color: rgba(85, 136, 221, 1);
          transform: scale3d(1, 1, 1);
        }
      }
      &.hide {
        opacity: 0;
      }
    }
  }
  tbody td {
    border: 1px solid @greydd;
  }
}
</style>

